package com.acooly.module.openapi.client.provider.hx.utils;

import com.acooly.core.utils.Encodes;
import com.acooly.module.openapi.client.api.exception.ApiClientException;

import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class StringHelper {

    // 转换为标准格式（避免自闭合的问题）
    public static String asXml(Element body) {
        OutputFormat format = new OutputFormat();
        format.setEncoding("UTF-8");
        format.setExpandEmptyElements(true);
        StringWriter out = new StringWriter();
        XMLWriter writer = new XMLWriter(out, format);
        try {
            writer.write(body);
            writer.flush();
        } catch (IOException e) {
            log.info("XML转换为标准格式=>单闭合节点变双节点转换异常!");
            throw new ApiClientException("XML转换为标准格式=>单闭合节点变双节点转换异常!");
        }
        return out.toString();
    }

    public static byte[] getBytes(String content, String charset) {
        if (isNULL(content)) {
            content = "";
        }
        if (isBlank(charset))
            throw new IllegalArgumentException("charset can not null");
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
        }
        throw new RuntimeException("charset is not valid,charset is:" + charset);
    }

    public static boolean isNULL(String str) {
        return str == null;
    }

    public static boolean isBlank(String str) {
        int strLen;
        if ((str == null) || ((strLen = str.length()) == 0))
            return true;

        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 生成不重复随机字符串包括字母数字
     *
     * @param len
     * @return
     */
    public static String generateRandomStr(int len) {
        //字符源，可以根据需要删减
        String generateSource = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String rtnStr = "";
        for (int i = 0; i < len; i++) {
            //循环随机获得当次字符，并移走选出的字符
            String nowStr = String.valueOf(generateSource.charAt((int) Math.floor(Math.random() * generateSource.length())));
            rtnStr += nowStr;
            generateSource = generateSource.replaceAll(nowStr, "");
        }
        return rtnStr;
    }

    /**
     * 将map中的值转化为字符，并以|分开
     *
     * @param params
     * @return
     */
    public static String mapToStr(Map<String, Object> params) {
        StringBuffer returnStr = new StringBuffer();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            returnStr.append(entry.getValue() + "|");
        }
        return returnStr.substring(0, returnStr.length() - 1);
    }

    /**
     * 将map中的key和value转化为字符，并以index分开
     *
     * @param params
     * @return
     */
    public static String mapToStrByIndex(Map<String, Object> params, String index) {
        StringBuffer returnStr = new StringBuffer();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            returnStr.append(entry.getKey() + "=" + entry.getValue() + index);
        }
        return returnStr.substring(0, returnStr.length() - index.length());
    }

    /**
     * 将byte[] 转换成字符串
     *
     * @return
     */
    public static String byte2Hex(byte[] srcBytes) {
        StringBuilder hexRetSB = new StringBuilder();
        for (byte b : srcBytes) {
            String hexString = Integer.toHexString(0x00ff & b);
            hexRetSB.append(hexString.length() == 1 ? 0 : "").append(hexString);
        }
        return hexRetSB.toString();
    }

    /**
     * 将16进制字符串转为转换成字符串
     *
     * @param source
     * @return
     */
    public static byte[] hex2Bytes(String source) {
        byte[] sourceBytes = new byte[source.length() / 2];
        for (int i = 0; i < sourceBytes.length; i++) {
            sourceBytes[i] = (byte) Integer.parseInt(source.substring(i * 2, i * 2 + 2), 16);
        }
        return sourceBytes;
    }

    /**
     * 组装跳转url
     *
     * @param redirectUrl
     * @param redirectParams
     * @return
     */
    public static String getRedirectUrl(String redirectUrl, Map<String, String> redirectParams) {
        StringBuffer stringBuffer = new StringBuffer();
        for (Map.Entry<String, String> entry : redirectParams.entrySet()) {
            stringBuffer.append(entry.getKey() + "=" + Encodes.urlEncode(entry.getValue()) + "&");
        }
        return redirectUrl + "?" + stringBuffer.substring(0, stringBuffer.length() - 1);
    }

    /**
     * 组装form表单
     *
     * @param url
     * @param params
     * @return
     */
    public static String buildFormHtml(String url, Map<String, Object> params, String title) {
        StringBuffer html = new StringBuffer();
        html.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01Transitional//EN\">");
        html.append(
                "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" /><title>" + title + "</title></head>");

        StringBuffer formhtml = new StringBuffer();
        formhtml.append("<form accept-charset=\"utf-8\" id=\"epayredirect\" name=\"epayredirect\" action=\"" + url
                + "\" method=\"post\">");

        for (Map.Entry<String, Object> entry : params.entrySet()) {
            formhtml.append(
                    "<input type=\"hidden\" name=\"" + entry.getKey() + "\" value=\"" + entry.getValue() + "\"/>");
        }

        formhtml.append("<input type=\"submit\" value=\"submit\" style=\"display:none;\"></form>");
        formhtml.append("<script>document.forms['epayredirect'].submit();</script>");

        html.append(formhtml.toString());
        html.append("<body></body></html>");
        return html.toString();
    }
}
